// Copyright (C) 1953-2022 NUDT
// Verilog module name - packet_digest_send
// Version: PDS_V1.0
// Created:
//         by - fenglin 
//         at - 5.2022
////////////////////////////////////////////////////////////////////////////
// Description:
//         packet digest Send
///////////////////////////////////////////////////////////////////////////

`timescale 1ns/1ps

module packet_digest_send(
    i_clk,
    i_rst_n,
    
    i_md_valid,
    iv_md,  
    i_pkt_bufid_wr,
    iv_pkt_bufid,
    o_pkt_bufid_ack,
    
    o_md_wr,
    ov_md,
    i_md_ack,    
    md_send_state
);

// I/O
// clk & rst
input                   i_clk;
input                   i_rst_n;
//input
input                   i_md_valid;
input       [299:0]     iv_md;
input                   i_pkt_bufid_wr;
input       [8:0]       iv_pkt_bufid;
output  reg             o_pkt_bufid_ack;
//output
output  reg             o_md_wr;
output  reg [299:0]     ov_md;
input                   i_md_ack; 
output  reg [1:0]       md_send_state;

//temp ov_md and ov_pkt for discarding pkt while the fifo_used_findows is over the threshold 
//internal wire&reg
localparam  idle_s         				= 2'b00,
            wait_des_ack_s  			= 2'b01;
        
always@(posedge i_clk or negedge i_rst_n)
    if(!i_rst_n) begin
        o_pkt_bufid_ack     <= 1'b0;    
        o_md_wr             <= 1'b0;
        ov_md               <= 300'b0;
        md_send_state       <= idle_s;
    end
    else begin
        case(md_send_state)
            idle_s:begin
                if(i_pkt_bufid_wr == 1'b1 && i_md_valid == 1'b1)begin//when descriptor come,pkt_bufid_wr have been already
                    o_pkt_bufid_ack     <= 1'b1;
                    ov_md[148:140]      <= iv_pkt_bufid;
                    ov_md[299:149]      <= iv_md[299:149];
                    ov_md[139:0]        <= iv_md[139:0] ;
                    o_md_wr             <= 1'b1;
                    md_send_state       <= wait_des_ack_s;
                end
                else if(i_pkt_bufid_wr == 1'b0 && i_md_valid == 1'b1)begin
                    o_pkt_bufid_ack     <= 1'b0;
                    o_md_wr             <= 1'b0;
                    ov_md               <= 300'b0;
                    md_send_state       <= idle_s;  
                end
                else begin
                    o_pkt_bufid_ack     <= 1'b0;
                    o_md_wr             <= 1'b0;
                    ov_md               <= 300'b0;                                       
                    md_send_state       <= idle_s;
                end				

            end             
            wait_des_ack_s:begin
                o_pkt_bufid_ack     <= 1'b0;           
                if(i_md_ack == 1'b1) begin
                    ov_md          <= 300'b0;
                    o_md_wr        <= 1'b0;
                    md_send_state  <= idle_s;
                end
                else begin
                    ov_md          <= ov_md;
                    o_md_wr        <= o_md_wr;
                    md_send_state  <= wait_des_ack_s;
                end               
            end
            default:begin
                o_pkt_bufid_ack    <= 1'b0;      
                o_md_wr            <= 1'b0;
                ov_md              <= 300'b0;
                md_send_state      <= idle_s;
                end
        endcase
    end
	
//reg [15:0]      rv_pds_cnt/*synthesis noprune*/;              
//always@(posedge i_clk or negedge i_rst_n)
//    if(!i_rst_n) begin
//        rv_pds_cnt              <= 16'b0 ;
//    end
//    else begin    
//        if(i_md_ack == 1'b1) begin//head
//            if(ov_md[114:112] == 3'h5)begin
//                rv_pds_cnt          <= rv_pds_cnt + 1'b1 ;
//            end
//            else begin
//                rv_pds_cnt          <= rv_pds_cnt;                 
//            end
//	    end
//		else begin
//            rv_pds_cnt          <= rv_pds_cnt;                 
//        end
//    end	
//
endmodule